//@author A0096466N
//
// **********
//
// mark class changes the status of a task
// in the vector store
// in the txt store
// and in the currently displayed UI
//
// **********

#include "Mark.h"

Mark::Mark(void) {

}

Mark::~Mark(void) {

}

string Mark::execute(Task & task, vector<Task> & forUIDisplay, vector<Task> & store) {

	ofstream writeFile;
	writeFile.open(FILENAME_LOGGER.c_str(), ofstream::out | ofstream::app);
	writeFile << "Attempting to mark" << endl;
	writeFile.close();

	// if it is not empty, we are marking via UNDO function
	if(task.getTaskName() == EMPTY) {
		if(task.getTaskLine() == NIL) {
			throw exception("Invalid line number");
		}
		
		if(task.getTaskLine() > forUIDisplay.size() || task.getTaskLine() < 0) {
			throw exception("Invalid line number");
		}
	
		string modStatus = task.getModifiedStatus();
		if(modStatus == EMPTY) {
			throw exception("Nothing to mark to");
		}
	
		if(modStatus != DONE && modStatus != WIP && modStatus != WORK_IN_PROGRESS && modStatus != CMI
			&& modStatus != ARCHIVE) {
				throw exception("Invalid status type. Available statuses: wip/done/cmi/archive");
		}
		//collection of data in case user wants to UNDO
		int userTaskLine = task.getTaskLine();
		task.changeTaskName(forUIDisplay[userTaskLine-1].getTaskName());
		task.changeStatus(forUIDisplay[userTaskLine-1].getStatus());
	}

	if(task.getModifiedStatus() == WORK_IN_PROGRESS) {
		task.changeModifiedStatus(WIP);
	}

	//marking in vector<Task> _store
	markInStore(task,store);
			
	// marking from txt file
	markInStorage(task,store);

	// marking from currently displayed list
	markInUIDisplay(task,forUIDisplay);

	// settling UI Feedback
	string data = "marked '";
	
	if(task.getStatus() != task.getModifiedStatus() && task.getModifiedStatus() != EMPTY) {
		data += task.getTaskName();
		data += MARK_FEEDBACK1;
		data += task.getModifiedStatus();
		data += MARK_FEEDBACK2;
	} else {
		data = MARK_SAME_STATUS_FEEDBACK;
	}
	return data;
}

void Mark::markInStore(Task & task, vector<Task> & store) {
	ofstream writeFile;
	writeFile.open(FILENAME_LOGGER.c_str(), ofstream::out | ofstream::app);
	writeFile << "Attempting to mark in store" << endl;
	writeFile.close();
	
	assert(task.getModifiedStatus() != EMPTY);

	for(vector<Task>::iterator iter = store.begin(); iter != store.end(); iter++) {
		Task currentTask = *iter;
	
		// all the conditions is to confirm in the case of similar tasknames
		if(currentTask.getTaskName() == task.getTaskName()) {
			if(currentTask.getStatus() == task.getStatus()) {
				if(task.getModifiedStatus() != EMPTY) {
					(*iter).changeStatus(task.getModifiedStatus());
					break;
				} else {
					throw exception("Mark error");
				}
			}
		}
	}
}

void Mark::markInStorage(Task & task, vector<Task> & store) {

	ofstream writeFile;
	writeFile.open(FILENAME_LOGGER.c_str(), ofstream::out | ofstream::app);
	writeFile << "Attempting to mark in TXT storage" << endl;
	writeFile.close();

	vector<string> forTxtRewrite;
	Storage storage;
	Parser parse;
	string data;

	for(vector<Task>::iterator iter = store.begin(); iter != store.end(); iter++) {
		data = parse.convertToString(*iter);
		forTxtRewrite.push_back(data);
	}
	storage.rewrite(forTxtRewrite);
}

void Mark::markInUIDisplay(Task & task, vector<Task> & forUIDisplay) {
	
	ofstream writeFile;
	writeFile.open(FILENAME_LOGGER.c_str(), ofstream::out | ofstream::app);
	writeFile << "Attempting to mark in UI Display" << endl;
	writeFile.close();

	assert(task.getModifiedStatus() != EMPTY);


	for(vector<Task>::iterator iter = forUIDisplay.begin(); iter != forUIDisplay.end(); iter++) {
		Task currentTask = *iter;
		
		// all the conditions is to confirm in the case of similar tasknames
		if(currentTask.getTaskName() == task.getTaskName()) {
			if(currentTask.getStatus() == task.getStatus()) {
				if(task.getModifiedStatus() != EMPTY) {
					(*iter).changeStatus(task.getModifiedStatus());
					break;
				} else {
					throw exception("Mark Error");
				}
			}
		}

	}
}